package middleware

import (
	"errors"
	"fmt"
	"github.com/gin-gonic/gin"
	"github.com/go-playground/validator/v10"
	"go-web-admin/common/buzzerror"
	"go-web-admin/response"
	"net/http"
	"reflect"
)

// ErrorHandler Gin 中间件统一捕获并返回 JSON 错误信息
func ErrorHandler(c *gin.Context) {
	c.Next()

	for _, err := range c.Errors {
		// 是否是自定义错误
		var buzzErr *buzzerror.BuzzError
		// 检查是否是 validator.ValidationErrors
		var ve validator.ValidationErrors

		if errors.As(err.Err, &buzzErr) {
			response.Fail(c, buzzErr.Code, buzzErr.Message)
			return
		} else if errors.As(err.Err, &ve) {
			// 使用 map 存储字段名和错误消息
			errorDetails := make(map[string]string)
			for _, fe := range ve {
				// 尝试从绑定的结构体获取 msg tag
				if bindVal, exists := c.Get("BIND_STRUCT"); exists {
					// 通过反射获取结构体类型
					typ := reflect.Indirect(reflect.ValueOf(bindVal)).Type()
					if field, ok := typ.FieldByName(fe.Field()); ok {
						msg := field.Tag.Get("msg")
						if msg != "" {
							// 使用 json tag 作为键（如果存在），否则使用字段名
							jsonTag := field.Tag.Get("json")
							if jsonTag != "" {
								errorDetails[jsonTag] = msg
							} else {
								errorDetails[fe.Field()] = msg
							}
							continue
						}
					}
				}
				// 如果 msg tag 不存在，使用默认错误消息
				errorDetails[fe.Field()] = fmt.Sprintf("Field validation for '%s' failed on the '%s' tag", fe.Field(), fe.Tag())
			}
			response.FailWithDetails(c, http.StatusBadRequest, errorDetails)
			return
		} else {
			response.FailUnknownError(c) // 未知异常
			return
		}
	}
}
